function [A] = struct2array(s, indexMap)
%STRUCT2ARRAY 将结构体转换至二维数组
%
% Input Arguments:
% s: 各域为数组的结构体
% indexMap: 各域为数组的结构体，各域的名称与s相同，各域的维数比s相应域的维数小1，各域的各元素分别表示s中对应的元素在A中对应的列数，NaN表示不转换，负数表示取负值
%
% Output Arguments:
% A: 二维数组，s各域的元素沿最后一维与indexMap中对应元素指定的A的列相同，当s中各域超过indexMap相应域的一维（不计尺寸为1的最后一维）的尺寸不同时，长度不足的补0

fullFieldNames = fieldnames(indexMap);
fullFieldBaseNumsOfEle = zeros(1, length(fullFieldNames));
for i=1:length(fullFieldNames)
    fullFieldBaseNumsOfEle(1, i) = numel(indexMap.(fullFieldNames{i}));
end
startcolumn = 1;
for i=1:length(fullFieldNames)
    sz = size(indexMap.(fullFieldNames{i}));
    if sz(1, end) == 1
        secToLastDim = length(sz) - 1; % 倒数第二维的尺寸
    else
        secToLastDim = length(sz);
    end
    lastDimSize = size(s.(fullFieldNames{i}), secToLastDim+1);
    % 添加该初始化用以避免indexMap的最后一列为NaN导致的A的列数的缺少 % TODO: A的列数不是固定的，不需要填充所有列
    A(1:lastDimSize, startcolumn:startcolumn+fullFieldBaseNumsOfEle(1, i)-1) = NaN * ones(lastDimSize, fullFieldBaseNumsOfEle(1, i));
    startcolumn = startcolumn+fullFieldBaseNumsOfEle(1, i);
end
for i=1:length(fullFieldNames)
    sz = size(indexMap.(fullFieldNames{i}));
    if sz(1, end) == 1
        secToLastDim = length(sz) - 1; % 倒数第二维的尺寸
    else
        secToLastDim = length(sz);
    end
    lastDimSize = size(s.(fullFieldNames{i}), secToLastDim+1);
    for j=1:fullFieldBaseNumsOfEle(1, i)
        arrColIdx = indexMap.(fullFieldNames{i})(j); % 使用线性索引
        if ~isnan(arrColIdx)
            linearIdx = j:fullFieldBaseNumsOfEle(1, i):(j+(lastDimSize-1)*fullFieldBaseNumsOfEle(1, i)); % NOTE: 与MATLAB使用的以列为主的索引方法相关
            A(1:length(linearIdx), abs(arrColIdx)) = sign(arrColIdx) * s.(fullFieldNames{i})(linearIdx); %#ok<AGROW> % 使用线性索引
        end
    end
end
end